std::string是ANSI,但std::wstring是Unicode如果要定义Unicode,只需要在正常的ANSI字符串前加上“L”就可以了。wchar_t* un = L"China!";char* an = "China!";
string s("hello");
string对象要获得C风格表示,可使用成员函数c_str()
在C++中,字符串是以空字符(\0)结尾的字符数组。
可以像其他数组那样声明并初始化字符串:
char carr[] = {'w','w','u','h','n','\0'};
也可以用字面量初始化字符串的简捷方式:
char carr[] = "wwuhn";
这种初始化方法不需要使用空字符,而是由编译器自动添加。
当然也可以使用指针的方式:
char *cp = "wwuhn";
字符串的字面量会保存到内存的数据段,字符串以外的字面量会以代码的形式存在。数组初始化不一样,其右值的字符串保存在栈中。
不同的是,carr是常量,而cp是变量,但cp指向的却是字面量,相当于常量,不能单个更改。
在将各种类型的数据构造成字符串时,sprintf 的强大功能很少会让你失望。由于sprintf 跟printf 在用法上几乎一样,只是打印的目的地不同而已,前者打印到字符串中,后者则直接在命令行上输出。这也导致sprintf 比printf 有用得多。
字符可以作为右值赋值给字符数组或string字符串;
C++的函数库中提供了一些用来处理字符串的函数。这些函数在库cstring中。
C++还提供了一个string类来处理字符串
空字符'\0'标记字符数组中存储的C 字符串的结束。如果字符数组以这种方式使用,该数组就称为C 字符串变量。虽然空字符'\0'要写成两个符号,但实际只代表一个字符,可以用char 类型的变量或者字符数组的索引变量来存储它。
不能用=对C 字符串变量进行赋值。用==测试C 字符串相等性也得不到你希望的结果。原因很简单,因为C 字符串和C 字符串变量本质上是数组。
为C 字符串变量赋值不像为其他类型的变量赋值那么简单。以下语句非法:
char aString[10];
aString = "Hello";
虽然可在声明时用等号为C 字符串变量赋值,但在程序的其他任何地方都不能这样做。从技术上说,在声明时使用等号,就像下面这样:
char happyString[7] = "DoBeDo";
它其实是一个初始化操作,而不是赋值操作。要为C 字符串变量赋值,必须采取其他方式。
可采取许多不同的方式为C 字符串变量赋值。最简单的是使用预定义函数strcpy,
strcpy(aString, "Hello");
这也是为什么将后面的值复制到前面的值,而不是返回一个新的存储空间的指针的原因。
这会将aString 的值设为"Hello"。遗憾的是,strcpy 函数的这个版本不检查复制的字符串是否超过字符串变量(第一个参数)的长度。
许多(但并非全部)C++版本还提供了strcpy 的一个更安全的版本。这个安全版本要拼写成strncpy(多了一个n)。strncpy 函数要获取第3 个参数,指定最多能复制多少字符。
char anotherString[10];
strncpy(anotherString, aStringVariable, 9);
使用这个strncpy 函数,最多能从C 字符串变量aStringVariable 中复制9 个字符(包括'\0'),无论aStringVariable 中的字符串有多长。
也不能在表达式中使用操作符==测试两个C 字符串是否相等。更糟的是,可以为C 字符串使用==,但作用不是测试C 字符串是否相等。所以,用==测试两个C 字符串的相等性可能得到错误结果,而且编译器不报告任何错误!要测试两个C 字符串是否相等,可以使用预定义函数strcmp。例如下面的代码:
if (strcmp(cString1, cString2))
cout << "The strings are NOT the same.";
else
cout << "The strings are the same.";
注意,strcmp 函数的工作方式可能和你想的不同。两个字符串不匹配,结果反而是true。strcmp 函数每次比较C 字符串参数的一个字符。任何时候只要cString1 的一个字符的数值编码小于cString2 的对应字符的数值编码,测试就会停止,并返回一个负数。
如果cString1 的字符大于cString2 的对应字符,则返回一个正数(strcmp 的有些实现返回字符编码的差值,但不应依赖于此)。两个C 字符串完全相同,则返回0。字符比较依据的是词典顺序(lexicographic order)。它的重点是,两个字符串采用全部大写或小写的形式,词典顺序就和字母顺序一样。
基于词典顺序,在C 字符串比较结果是小于、大于或者等于的情况下,strcmp 分别返回负值、正值或零。在if 或循环语句中将strcmp 作为布尔表达式使用,在字符串不相等的前提下,返回的所有非零值都被转换成true;在字符串相等的前提下,返回的零值被转换成false。所以在测试C 字符串的相等性时,务必记住这一反转逻辑。
string 类在名称同为
#include <string>
using namespace std;
string 类的默认构造函数将string 对象初始化成空字符串,另一个构造函数获取一个C 字符串作为参数,将string 对象初始化成一个值来表示由参数给定的字符串。例如:
string s1, s2("Hello");
从技术角度看,std::string是对std::basic_string模板进行char实例化的类型别名。
string提供一些边界检查、赋值语义以及比较操作,还有串联、子字符串提取以及子字符串或字符的替换。
标准库还提供string_view类,这是各类字符串表示的只读视图,可用于简单替换const string&&,而且不会带来开销,它从不复制字符串。
compelling reason to use C-style strings, use std::string (defined in the
Prefer std::string_view over std::string for read-only strings, unless you already have a std::string.
There is a special version of getline() that lives outside the istream class that is used for reading in variables of type std::string. This special version is not a member of either ostream or istream, and is included in the string header. Here is an example of its use:
#include <string> #include <iostream> int main() { using namespace std; string strBuf; getline(cin, strBuf); cout << strBuf << endl; return 0; }
string really is a typedef for a template specialization basic_string<char> and that they omit an optional argument relating to memory management. (This aspect is discussed later this chapter and in Appendix F,“The string Template Class.”) The type size_type is an implementation-dependent integral type defined in the string header file.The class defines string::npos as the maximum possible length of the string.Typically, this would equal the maximum value of an unsigned int.Also the table uses the common abbreviation NBTS for null-byte-terminated string—that is, the traditional C string, which is terminated with a null character.